import { OrthographicCamera, PerspectiveCamera, Scene, WebGLRenderer } from "three";
import { ClockEvent, ClockEvents } from "../Types/BasicType";

export default class Render {
  mainCamera: PerspectiveCamera;
  mainScene: Scene;

  hudCamera: OrthographicCamera;
  hudScene: Scene;

  r: WebGLRenderer;

  private clockEvent: ClockEvents = {};

  /**
   * 构造函数
   * @param _antialias 渲染器是否是平滑的，抗锯齿的
   * @param _selector canvas元素，不指定则会自动创建
   */
  constructor(_antialias: boolean) {
    let parameters: any = {
      context: canvas.getContext("webgl", { antialias: _antialias }),
      canvas,
    };
    this.r = new WebGLRenderer(parameters);
    this.mainScene = new Scene();
    this.mainCamera = new PerspectiveCamera();

    this.hudScene = new Scene();
    this.hudCamera;
  }
  /**
   * 设置场景
   * @param active 设置场景的委托函数
   * @returns 返回当前类
   */
  setScene(active?: (s: Scene, d?: Render) => void): Render {
    active && active(this.mainScene, this);
    return this;
  }
  /**
   * 设置相机
   * @param active 设置相机的委托函数
   * @returns 返回当前类
   */
  setCamera(active?: (c: PerspectiveCamera, d?: Render) => void): Render {
    active && active(this.mainCamera, this);
    return this;
  }
  /**
   * 设置渲染器
   * @param active 设置渲染器的委托函数
   * @returns 返回当前类
   */
  setRender(active?: (r: WebGLRenderer, d?: Render) => void): Render {
    active && active(this.r, this);
    return this;
  }
  /**
   * 判断是否存在时钟事件
   * @param eventName 时间名称
   * @returns 布尔值
   */
  hasClockEvent(eventName: string) {
    return !!this.clockEvent[eventName];
  }
  /**
   * 添加时钟事件
   * @param eventName 事件名称
   * @param event 事件函数
   */
  addClockEvent(eventName: string, event: ClockEvent) {
    if (this.clockEvent[eventName]) throw "已存在该事件，请勿重复添加！";
    this.clockEvent[eventName] = event;
  }
  /**
   * 删除时钟事件
   * @param eventName 事件名称
   */
  removeClockEvent(eventName: string) {
    delete this.clockEvent[eventName];
  }
  /**
   * 清空时钟事件
   */
  clearClockEvent() {
    this.clockEvent = {};
  }

  oldS = 0;
  /** 动画循环的id */
  animationId: number;
  /**
   * 动画循环事件
   * @param t 动画到目前运行了多少秒
   */
  animate(t?: number) {
    // if (this.resetSize()) {
    //   this.updateCameraAspect();
    // }
    let s = Math.trunc(t / 1000 / 10);
    if (s != this.oldS) {
      this.r.renderLists.dispose();
      this.oldS = s;
    }
    this.animationId = requestAnimationFrame(this.animate.bind(this));
    for (const key in this.clockEvent) {
      this.clockEvent[key](t);
    }
    this.r.clear();
    this.r.render(this.mainScene, this.mainCamera);
    this.r.clearDepth();
    this.r.render(this.hudScene, this.hudCamera);
  }
}
